EP7. 모델튜닝 — SFT, RLHF, DPO

사전학습된 LLM의 파라미터를 목적에 맞게 미세 조정하는 세 기법(SFT·RLHF·DPO)의 원리·데이터·손실 함수를 비교하고, instruction-following 능력과 선호도 정렬(alignment)을 달성하는 방법을 정리합니다.


0. 사전 필수 용어 (선행지식)

사전학습 (Pre-training) 수십억~수조 개 토큰 데이터로 언어 모델의 파라미터를 초기화하는 과정입니다. 다음 토큰 예측 손실(next-token prediction loss)로 학습합니다. 비유: 시험을 위한 교과서 전체 독파. → §1 "주제 정의" 및 §3 "핵심 개념" 전반에서 참조.

손실 함수 (Loss Function) 모델 예측과 정답 간 오차를 수치화하는 함수로, 역전파(backpropagation)의 기준이 됩니다. SFT는 교사 강제(teacher forcing) CE loss, DPO는 선호도 대비 손실을 사용합니다. → §6 "핵심 원리"에서 구체적으로 다룸.

로그 확률 (Log Probability, logprob) 시퀀스 전체가 생성될 확률을 토큰별 소프트맥스 확률값의 로그 합으로 계산한 단일 스칼라입니다. 비유: 문장 전체의 신뢰도 점수. → §3 RLHF 메커니즘, §6 원리에서 핵심 개념.

LoRA / QLoRA Low-Rank Adaptation: 모델 전체 재학습 대신 소규모 저랭크(low-rank) 행렬 두 개를 추가하여 학습하는 PEFT 기법입니다. QLoRA는 4-bit 양자화를 결합해 소비자 GPU에서도 실행됩니다. 비유: 교과서에 포스트잇 메모만 추가하는 방식. → §3·§4·§7에서 핵심 구현 경량화 방법으로 사용.

PPO (Proximal Policy Optimization) RLHF에서 보상값이 급격히 커지는 현상(보상 해킹)을 방지하는 강화 학습 알고리즘입니다. 정책 변화량에 클리핑(clipping) 제약을 두어 안정적 학습을 유도합니다. → §3 RLHF 메커니즘, §9 한계에서 reward hacking과 함께 등장.

📚 참고 — Andrej Karpathy "State of GPT" (https://youtu.be/bZQun8Y4L2A) 에서 SFT→RLHF 파이프라인을 시각적으로 설명합니다.


1. 주제 정의

모델튜닝(SFT / RLHF / DPO)은 사전학습된 LLM의 출력을 원하는 방향으로 조정하는 사후 학습(post-training) 기법으로, 지시 이행성(instruction-following ability)과 인간 선호도 정렬(alignment)을 목표로 합니다.

핵심 아이디어: 사전학습이 "언어를 배우는 단계"라면, 사후 학습 튜닝은 "어떤 방향으로 말할지를 조정하는 단계"입니다.


2. 풀려는 문제

  • 문제 1 — Base 모델의 instruction-following 부재: 사전학습만 된 모델은 질문에 대해 다음 토큰을 예측할 뿐, 사용자의 지시에 따라 응답 방향을 바꾸지 못합니다. SFT가 이를 해결합니다.
  • 문제 2 — 시스템 프롬프트 무효화: instruction 없는 SFT 학습 모델은 시스템 프롬프트 지시가 유저 프롬프트와 거의 차이 없이 처리됩니다.
  • 문제 3 — 인간 선호도와의 괴리: 문법적으로 옳지만 유해하거나 불성실한 답변을 생성하는 문제를 RLHF/DPO가 해결합니다.
  • 문제 4 — 보상 모델 구축 비용: RLHF는 별도 보상 모델(reward model) 학습이 필요해 비용·복잡도가 높습니다. DPO가 이를 제거합니다.

💡 실무 노하우 — 프로덕션에서는 SFT 없이 RLHF/DPO를 적용하면 안 됩니다. SFT가 instruction 분포를 먼저 학습해야 선호도 튜닝이 유효합니다.


3. 핵심 개념·구조

SFT (Supervised Fine-Tuning)

  • 데이터: {"instruction": "...", "input": "...", "output": "..."} 형태의 정답 전용 데이터셋
  • 학습 방식: 질문(instruction + input) 부분은 기존 모델 가중치로 어텐션 계산, 답변 토큰 생성 부분만 손실 함수에 반영
  • 핵심 효과: instruction이 모델의 시스템 프롬프트로 작동 → 다양한 instruction 하에 동일 질문의 답변 방향이 달라지도록 학습

RLHF (Reinforcement Learning from Human Feedback)

  • 데이터: {"prompt": "...", "response_1": "...", "response_2": "...", "preferred": 1} — 인간이 선호도 레이블 부여
  • 학습 방식: 선택된 답변 시퀀스의 로그 확률(logprob)에 보상값(reward)을 곱해 손실 함수 구성 → 역전파
  • 보상 반영 위치: 주로 마지막 어텐션 레이어의 FFN(Feed Forward Network), 일부 어텐션 가중치
  • PPO로 보상값 폭주 방지

DPO (Direct Preference Optimization)

  • 데이터: {"prompt": "...", "chosen": "...", "rejected": "..."} — 선택/거부 쌍
  • 학습 방식: 보상 모델 없이 chosen·rejected 두 시퀀스의 로그 확률 차이를 직접 손실로 사용
  • 목표: 차이를 최대화 → chosen 확률 ↑, rejected 확률 ↓
SFT 파이프라인
──────────────────────────────────────────
사전학습 Base 모델
        │
        ▼  instruction+input+output 데이터
   SFT 학습 (답변 토큰만 CE loss)
        │
        ▼
  Instruction-Following 모델

RLHF 파이프라인
──────────────────────────────────────────
SFT 모델
        │
        ▼  (prompt, chosen, rejected) + 인간 선호 레이블
  보상 모델(Reward Model) 학습
        │
        ▼  PPO + 보상 신호
  정책 모델(Policy Model) 업데이트
        │
        ▼
  선호도 정렬 모델

DPO 파이프라인
──────────────────────────────────────────
SFT 모델
        │
        ▼  (prompt, chosen, rejected) 쌍
  logprob(chosen) - logprob(rejected) 차이 최대화
        │
        ▼
  선호도 정렬 모델 (보상 모델 불필요)

4. 구현 가이드 (Do It Yourself)

시작 전 (Before you begin)

본 섹션 완료 시 SFT·DPO 학습 루프를 로컬 GPU 환경에서 실행할 수 있습니다.

선수 조건: - Python 3.10+ - pip install transformers trl datasets peft accelerate bitsandbytes - HuggingFace 토큰 (HF_TOKEN) — 환경 변수 - GPU (최소 VRAM 8GB, QLoRA 사용 시)

소요 시간: 약 30~60분 (GPU 의존).


Step 1 — 데이터 준비 (SFT instruction dataset)

목표: instruction-input-output 3열 데이터셋 로드.

from datasets import load_dataset

dataset = load_dataset("tatsu-lab/alpaca", split="train")

이 코드는 HuggingFace Hub에서 공개된 Alpaca instruction 데이터셋을 로드합니다. instruction·input·output 컬럼이 포함되어 있습니다.

⚠️ 주의 — HF_TOKEN 환경 변수가 없으면 gated 모델 접근이 거부됩니다. huggingface-cli login 으로 사전 인증하세요.

💡 실무 노하우 — 데이터 품질이 양보다 중요합니다. 10만 건의 노이즈 데이터보다 1만 건의 고품질 instruction 쌍이 SFT 성능을 더 높입니다.

📚 참고 — HuggingFace Datasets (https://huggingface.co/docs/datasets)

✅ 확인: print(dataset[0]) 실행 시 instruction·input·output 키가 출력됩니다.


Step 2 — SFT 학습 (SFTTrainer)

목표: TRL의 SFTTrainer로 instruction-following 모델 학습.

from trl import SFTTrainer, SFTConfig
from transformers import AutoModelForCausalLM, AutoTokenizer

model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2-0.5B")
trainer = SFTTrainer(model=model, args=SFTConfig(output_dir="sft-out"),
                     train_dataset=dataset)
trainer.train()

SFTTrainer는 내부적으로 답변 토큰 부분만 손실 함수에 반영하고, instruction 부분은 마스킹합니다.

⚠️ 주의 — GPU VRAM 부족 시 load_in_4bit=True (QLoRA)를 사용하세요. bitsandbytes 설치 필수.

💡 실무 노하우 — gradient_checkpointing=True 설정으로 VRAM 사용량을 30~50% 줄일 수 있습니다.

📚 참고 — HuggingFace TRL SFTTrainer (https://huggingface.co/docs/trl/sft_trainer)

✅ 확인: 학습 로그에 loss 값이 단계별로 감소하면 정상입니다.


Step 3 — DPO 학습 (preference dataset + DPOTrainer)

목표: chosen/rejected 쌍 데이터로 선호도 정렬.

from trl import DPOTrainer, DPOConfig

trainer = DPOTrainer(model=sft_model, ref_model=ref_model,
                     args=DPOConfig(beta=0.1, output_dir="dpo-out"),
                     train_dataset=pref_dataset)
trainer.train()

beta=0.1은 KL 정규화 강도입니다. 값이 클수록 reference 모델에서 멀리 벗어나지 않게 제한됩니다.

⚠️ 주의 — ref_model은 SFT 완료 모델의 고정(frozen) 복사본입니다. 메모리가 2배 필요합니다.

💡 실무 노하우 — beta 값은 0.05~0.5 범위에서 실험하세요. 너무 낮으면 chosen/rejected 구분이 무너지고, 너무 높으면 학습이 정체됩니다.

📚 참고 — DPO 원논문 (https://arxiv.org/abs/2305.18290)

✅ 확인: rewards/chosenrewards/rejected보다 높게 유지되면 학습 방향이 정상입니다.


Step 4 — 평가 (eval loop)

목표: 학습된 모델의 instruction-following 품질 검증.

from transformers import pipeline

pipe = pipeline("text-generation", model="./sft-out")
print(pipe("Translate the following phrase into French: I love you")[0]["generated_text"])

✅ 확인: instruction에 맞는 출력("Je t'aime" 등)이 생성됩니다.


Step 5 — 동작 확인

SFT 학습 후 동일 입력에 instruction을 바꾸면 출력이 달라지는 것을 확인합니다.

입력: "I love you"
instruction="Translate the following phrase into French"  → "Je t'aime"
instruction="Translate the following phrase into Korean"  → "사랑해"

5. 적용 사례 (공신력 오픈소스 5가지+)

  • HuggingFace TRL (https://github.com/huggingface/trl) — SFTTrainer·DPOTrainer·PPOTrainer 통합 API. 현재 SFT/RLHF/DPO 표준 구현체로, DPOTrainerbeta 파라미터로 KL 정규화를 직접 조정합니다.
  • HuggingFace Transformers (https://github.com/huggingface/transformers) — AutoModelForCausalLM·AutoTokenizer·Trainer. 모든 모델 로드·토크나이저 처리의 기반.
  • HuggingFace PEFT (https://github.com/huggingface/peft) — LoRA·QLoRA 구현. RLHF 보상 반영 위치(마지막 FFN)에 경량 레이어를 추가하는 표준 방법.
  • LLaMA-Factory (https://github.com/hiyouga/LLaMA-Factory) — YAML 설정 한 파일로 SFT/RLHF/DPO/ORPO를 선택·실행하는 통합 CLI. 다국어 instruction 데이터셋 150+ 내장.
  • Axolotl (https://github.com/OpenAccess-AI-Collective/axolotl) — YAML 기반 fine-tuning 프레임워크. Flash Attention 2·NEFTune·packed sequences 등 학습 최적화를 설정 파일로 제어합니다.
  • vLLM (https://github.com/vllm-project/vllm) — fine-tuned 모델 inference 서빙. PagedAttention으로 VRAM 효율을 높이며 OpenAI-compatible API 제공.
  • Anthropic Python SDK (https://github.com/anthropics/anthropic-sdk-python) — RLHF 결과물인 Claude API 활용. model="claude-opus-4-7", model="claude-sonnet-4-6", model="claude-haiku-4-5-20251001" 세 모델 중 선택.
  • DeepSpeed (https://github.com/microsoft/DeepSpeed) — ZeRO-3 메모리 최적화로 RLHF 전체 학습 가능. 소비자 GPU 다중 구성에서 70B 모델 학습에 활용.

📚 참고 — 위 OSS들은 모두 GitHub stars 5K+ 또는 Anthropic·HuggingFace·Microsoft 공식 SDK/프레임워크입니다.


6. 핵심 원리

SFT 손실 함수

답변 토큰 부분만 Cross-Entropy Loss를 적용합니다. instruction과 input은 마스킹되어 그래디언트가 흐르지 않습니다. 같은 질문에 instruction이 다르면 다른 CE 타겟이 되어, 모델이 instruction 조건부 출력을 학습합니다.

L_SFT = -Σ log P(y_t | y_{<t}, x)   [y = 답변 토큰만]

DPO 손실 함수

보상 모델 없이 직접 선호도를 손실로 변환합니다. chosen 시퀀스 logprob과 rejected 시퀀스 logprob의 차이에 sigmoid를 적용합니다.

L_DPO = -log σ(β · (log π(y_w|x)/π_ref(y_w|x)
              - log π(y_l|x)/π_ref(y_l|x)))

β는 reference 모델 이탈 강도 조절 하이퍼파라미터입니다. RLHF-PPO 대비 구현 복잡도가 낮고, reward hacking이 없습니다.


7. 변형·확장

  • LoRA + SFT (QLoRA): 4-bit 양자화 + LoRA로 소비자 GPU(RTX 4090 24GB)에서 7B 모델 SFT 가능. bitsandbytes + PEFT 조합.
  • DPO 변형:
  • IPO (Identity Preference Optimization): DPO의 과적합 문제를 정규화로 해결.
  • KTO: chosen/rejected 쌍이 아닌 단일 응답에 binary 선호 레이블만 있어도 학습.
  • SimPO: reference 모델 없이 길이 정규화 포함 단순화된 DPO.
  • ORPO (Odds Ratio Preference Optimization): SFT와 선호도 학습을 단일 손실 함수로 통합. 별도 reference 모델 불필요.

8. 다른 도구·접근과의 비교 (3-way)

SFT vs RLHF vs DPO

항목 SFT RLHF DPO
데이터 instruction + 정답 쌍 선호도 레이블(인간) chosen/rejected 쌍
보상 모델 불필요 필요 (별도 학습) 불필요
구현 복잡도 낮음 높음 (PPO+RM 2단계) 중간
GPU 비용 중간 높음 (모델 2개+) 중간 (ref 모델 포함)
reward hacking 없음 있음 (PPO 클리핑 필요) 없음

TRL vs LLaMA-Factory vs Axolotl

항목 TRL LLaMA-Factory Axolotl
추상화 수준 중간 (Python API) 높음 (YAML CLI) 높음 (YAML config)
지원 기법 SFT/DPO/PPO/GRPO SFT/DPO/RLHF/ORPO SFT/QLoRA/Flash Attn
커스터마이징 자유도 높음 설정 파일 중심 설정 파일 중심

Full FT vs LoRA vs QLoRA

항목 Full Fine-Tuning LoRA QLoRA
VRAM (7B 기준) ~112GB ~24GB ~8GB
성능 최고 Full FT 90%+ LoRA와 유사
학습 속도 느림 빠름 중간

9. 한계·트레이드오프

  1. Compute·GPU 비용: RLHF-PPO는 policy 모델 + reference 모델 + reward 모델 등 최소 3개 모델을 동시에 메모리에 올려야 하므로 A100 80GB 4장 이상이 일반적입니다.
  2. Reward Hacking (RLHF 특유): 보상 모델이 근사(approximation)이므로, 모델이 보상 모델을 속이는 방향으로 과적합될 수 있습니다. 보상 모델의 분포 밖 프롬프트에서 특히 취약합니다.
  3. Data Quality 의존: SFT/DPO 모두 데이터 품질에 크게 의존합니다. 노이즈·편향이 있는 chosen/rejected 쌍은 정렬 방향을 왜곡합니다.

10. 최신 권장 패턴 (2026-05 기준)

(2026-05 기준, HuggingFace TRL 공식 문서·Rafailov 2023·Anthropic Constitutional AI 논문 출처)

  • DPO/SimPO가 RLHF-PPO 대체 추세: HuggingFace TRL 공식 예제가 DPO 중심으로 재편. PPO는 RLHF 연구 목적 외 프로덕션 적용이 줄어드는 추세 (HuggingFace TRL Docs, https://huggingface.co/docs/trl).
  • QLoRA + DPO 조합: 4-bit 양자화 + LoRA + DPO로 소비자 GPU(RTX 4090 단일)에서 7B 모델 선호도 정렬이 가능합니다. 논문: Dettmers et al. 2023 "QLoRA" (https://arxiv.org/abs/2305.14314).
  • Synthetic preference data (Constitutional AI 패턴): 인간 레이블 없이 모델 자체가 chosen/rejected 쌍을 생성·필터링하는 방식. Anthropic Constitutional AI (https://arxiv.org/abs/2212.08073) 에서 원형을 제시.

11. 메타인지 자기평가

본인 코드/시스템에 적용 가능한지 검증하는 절차입니다.

Step 1 — 현재 상태 점검

nvidia-smi
python -c "import trl; print(trl.__version__)"

Step 2 — 적용 가능성 평가 - 조건 1: GPU VRAM 8GB+ → QLoRA+DPO 적용 가능 - 조건 2: GPU VRAM 24GB+ → LoRA+SFT 전체 적용 가능 - 조건 3: instruction 데이터 500건 이상 → SFT 시작 가능 (소량이면 Alpaca 혼합 권장) - 조건 4: chosen/rejected 쌍 1,000건 이상 → DPO 유효

Step 3 — 점진 적용 1. SFT 먼저 적용 → instruction-following 기반 확보 2. 소규모 chosen/rejected 쌍 구축 (LLM-as-judge 활용 가능) → DPO 실험 3. W&B 또는 TensorBoard로 rewards/chosen·rewards/rejected 모니터링 4. beta 조정 (0.1 → 0.05 → 0.2 순으로 실험) 5. vLLM으로 서빙 테스트 후 프로덕션 배포


참조 모델

출처 적용 측면
HuggingFace TRL Docs (https://huggingface.co/docs/trl) SFT/DPO/PPO API
HuggingFace Transformers Docs (https://huggingface.co/docs/transformers) Tokenizer·Model·Trainer
Anthropic Constitutional AI 논문 (https://arxiv.org/abs/2212.08073) RLHF 원형
DPO 원논문 (Rafailov 2023, https://arxiv.org/abs/2305.18290) DPO 수학
InstructGPT 논문 (Ouyang 2022, https://arxiv.org/abs/2203.02155) SFT+RLHF 통합
QLoRA 논문 (Dettmers 2023, https://arxiv.org/abs/2305.14314) 소비자 GPU 학습
난이도
에피소드
질문
카드를 로딩 중...
답변

클릭하거나 Space를 눌러 뒤집기

0 / 0
학습 진도 0%
이동   Space 뒤집기   R 셔플